package cn.edu.gzgs.controller;

import cn.edu.gzgs.vo.ApiResponse;
import cn.edu.gzgs.dto.LoginRequestDTO;
import cn.edu.gzgs.dto.UserPermissionsDTO;
import cn.edu.gzgs.service.AuthService;
import cn.edu.gzgs.vo.TeacherLoginVO;
import cn.edu.gzgs.config.ratelimit.LoginRateLimit;
// OpenAPI 3 Annotations
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.security.sasl.AuthenticationException;

@Tag(name = "认证接口", description = "用户登录及权限获取") // 类级标签
@RestController
@RequestMapping("/api/auth")
@Slf4j
public class AuthController {

    private final AuthService authService;

    @Autowired
    public AuthController(AuthService authService) {
        this.authService = authService;
    }

    // 获取用户权限
    @Operation(summary = "获取用户权限", description = "根据用户ID获取该用户的菜单权限键列表", security = @io.swagger.v3.oas.annotations.security.SecurityRequirement(name = "bearerAuth"))
    @ApiResponses(value = {
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "成功获取权限",
                    content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = UserPermissionsDTO.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误",
                    content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = ApiResponse.class)))
    })
    @GetMapping("/users/{userId}/permissions")
    public ResponseEntity<ApiResponse<UserPermissionsDTO>> getUserPermissions(@PathVariable Long userId) {
        // 仅从SecurityContext中获取已认证的用户信息
        var authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || !authentication.isAuthenticated()) {
            // 认证信息为空或未认证，返回未授权
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(new ApiResponse<>(401, "请求未认证，请登录后再试", null));
        }

        // (可选)判断请求的用户ID是否与JWT中的用户ID一致
        String currentUsername = authentication.getName(); // 一般为用户名
        // 如果需要，可以在这里校验currentUsername对应的用户是否允许访问这个userId
        //（例如：用户只能查看自己的权限）

        // 调用业务服务获取权限
        try {
            UserPermissionsDTO permissions = authService.getUserPermissions(userId);
            ApiResponse<UserPermissionsDTO> response = new ApiResponse<>(0, "成功获取权限", permissions);
            log.info("用户: {} 请求获取用户ID: {} 权限成功", currentUsername, userId);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("请求获取用户ID: {} 权限失败: {}", userId, e.getMessage(), e);
            ApiResponse<UserPermissionsDTO> response = new ApiResponse<>(500, e.getMessage(), null);
            return ResponseEntity.status(500).body(response);
        }
    }

    // 登录接口
    @Operation(summary = "用户登录", description = "使用工号和密码进行登录，成功则返回用户信息和Token")
    @ApiResponses(value = {
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "登录成功",
                    content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = TeacherLoginVO.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "认证失败 (用户名或密码错误)",
                    content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = ApiResponse.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误",
                    content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = ApiResponse.class)))
    })
    @PostMapping("/login")
    @LoginRateLimit
    public ResponseEntity<ApiResponse<TeacherLoginVO>> login(@RequestBody LoginRequestDTO loginRequest) {
        log.info("用户登录请求: 工号 - {}", loginRequest.getUserNo());
        try {
            TeacherLoginVO loginData = authService.login(loginRequest);
            ApiResponse<TeacherLoginVO> response = new ApiResponse<>(0, "登录成功", loginData);
            log.info("用户: {} 登录成功", loginRequest.getUserNo());
            return ResponseEntity.ok(response);
        } catch (AuthenticationException e) {
            log.warn("用户: {} 登录认证失败: {}", loginRequest.getUserNo(), e.getMessage());
            ApiResponse<TeacherLoginVO> response = new ApiResponse<>(HttpStatus.UNAUTHORIZED.value(), e.getMessage(), null);
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
        } catch (Exception e) {
            log.error("用户: {} 登录时发生内部错误: {}", loginRequest.getUserNo(), e.getMessage(), e);
            ApiResponse<TeacherLoginVO> response = new ApiResponse<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "登录时发生内部错误: " + e.getMessage(), null);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

}